package edu.kpi.pzks2.queue;

import java.util.ArrayList;
import java.util.List;

import edu.kpi.pzks2.graph.Edge;
import edu.kpi.pzks2.graph.Node;
import edu.kpi.pzks2.tools.TaskGraphTools;
import edu.kpi.pzks2.ui.MainFrame;
import edu.uci.ics.jung.graph.Graph;

public class NodeStatistDescriptor {
    private Node node;
    
    private int criticalPathWeight;
    private int criticalPathLength;
    private int linksNum;
    private double normalizedSum;
    
    public NodeStatistDescriptor(
            Node node, 
            int criticalPathWeight, 
            int criticalPathLength, 
            int linksNum,
            float normalizedSum) {
        this.node = node;
        this.criticalPathWeight = criticalPathWeight;
        this.criticalPathLength = criticalPathLength;
        this.linksNum = linksNum;
        this.normalizedSum = normalizedSum;
    }
    
    public Node getNode() {
        return node;
    }
    
    public int getCriticalPathWeight() {
        return criticalPathWeight;
    }
    
    public int getCriticalPathLength() {
        return criticalPathLength;
    }

    public int getLinksNum() {
        return linksNum;
    }
    
    public double getNormalizedSum() {
        return normalizedSum;
    }
    
    private static int getCriticalPath(Graph<Node, Edge> graph, Node node, boolean isTime) {
        return TaskGraphTools.getCriticalPath(graph, node, isTime);
    }
    
    public static List<NodeStatistDescriptor> getNodeDescList(final Graph<Node, Edge> graph) {
        // Process max critical path (length)
        int maxP = 0;
        for (Node node : graph.getVertices()) {
            int currentP = getCriticalPath(graph, node, false);
            if (currentP > maxP) {
                maxP = currentP;
            }
        }
        MainFrame.showLogMessage("Max critical path length = " + maxP);
        
        // Process max critical path (time)
        int maxT = 0;
        for (Node node : graph.getVertices()) {
            int currentT = getCriticalPath(graph, node, true);
            if (currentT > maxT) {
                maxT = currentT;
            }
        }
        MainFrame.showLogMessage("Max critical path weight = " + maxT);
        
        final List<NodeStatistDescriptor> res = new ArrayList<NodeStatistDescriptor>();
        
        for (Node node : graph.getVertices()) {
            final int criticalP = getCriticalPath(graph, node, false);
            final int criticalT = getCriticalPath(graph, node, true);
            final float normalizedSum = criticalP / (float) maxP + criticalT / (float) maxT;
            final int linkNum = graph.getNeighborCount(node);
            final NodeStatistDescriptor desc = 
                    new NodeStatistDescriptor(node, criticalT, criticalP, linkNum, normalizedSum);
            res.add(desc);
        }
        
        return res;
    }
}
